import type {
  CrudExpose,
  PageQuery,
  PageRes,
  ScopeContext,
  TransformResProps,
  ValueResolveContext,
} from '@fast-crud/fast-crud';

import type { Ref } from 'vue';

import type { CodeQueryVO } from '#/api';

import { useAccess } from '@vben/access';

import { dict } from '@fast-crud/fast-crud';
import { isFunction, isString } from 'lodash-es';

import { useMessage } from '#/hooks/web/useMessage';
import { $t } from '#/locales';
import { dateUtil } from '#/utils/dateUtil';

/**
 * 公共的序号列
 *
 * @param crudExpose 为空时翻页重新计算，不为空则根据翻页累加
 */
export const indexColumn = (crudExpose?: CrudExpose) => {
  return {
    _index: {
      title: $t('common.title.seq'),
      type: 'number',
      column: {
        align: 'center',
        width: 50,
        // 禁止在列设置中选择
        columnSetDisabled: true,
        formatter: (context: ScopeContext) => {
          if (crudExpose) {
            const index = context.index ?? 1;
            const pagination = crudExpose.crudBinding.value.pagination;
            return (
              ((pagination?.page ?? 1) - 1) * pagination?.pageSize + index + 1
            );
          }
          return (context.index ?? 1) + 1;
        },
      },
      form: {
        show: false,
      },
    },
  };
};

/** 创建时间列 */
export const createdTimeAccurateColumn = ({
  searchShow = true,
  addShow = false,
  editShow = false,
}) => {
  return {
    createdTime: {
      title: $t('common.createdTime'),
      type: ['datetimerange'],
      viewForm: {
        render: ({ value }: ScopeContext) => {
          return <span>{value}</span>;
        },
      },
      search: {
        show: searchShow,
        col: { span: 10 },
        component: {
          showTime: {
            defaultValue: [
              dateUtil('00:00:00', 'HH:mm:ss'),
              dateUtil('23:59:59', 'HH:mm:ss'),
            ],
          },
          format: 'YYYY-MM-DD HH:mm:ss',
          // 传递给后端的值的格式化
          valueFormat: 'YYYY-MM-DD HH:mm:ss',
        },
        valueResolve({ form, key }: ValueResolveContext) {
          if (form[key]) {
            const extra = {
              [`${String(key)}_start`]: form[key]?.[0],
              [`${String(key)}_end`]: form[key]?.[1],
            };
            Reflect.deleteProperty(form, key);
            form.extra = extra;
          }
        },
      },
      addForm: { show: addShow },
      editForm: { show: editShow },
      column: {
        sorter: true,
        width: 180,
      },
    },
  };
};
/** 创建时间，查询框只显示日期，时间由后端自动补全 */
export const createdTimeColumn = ({
  searchShow = true,
  addShow = false,
  editShow = false,
}) => {
  return {
    createdTime: {
      title: $t('common.createdTime'),
      type: 'daterange',
      viewForm: {
        render: ({ value }: ScopeContext) => {
          return <span>{value}</span>;
        },
      },
      search: {
        show: searchShow,
        col: { span: 6 },
        component: {
          // 显示在页面的日期格式化
          format: 'YYYY-MM-DD',
          // 传递给后端的值的格式化
          valueFormat: 'YYYY-MM-DD',
          presets: [
            { label: '过去1周', value: [dateUtil().add(-7, 'd'), dateUtil()] },
            { label: '过去1月', value: [dateUtil().add(-1, 'M'), dateUtil()] },
            { label: '过去6月', value: [dateUtil().add(-6, 'M'), dateUtil()] },
            { label: '过去1年', value: [dateUtil().add(-1, 'y'), dateUtil()] },
            { label: '未来1周', value: [dateUtil(), dateUtil().add(7, 'd')] },
            { label: '未来1月', value: [dateUtil(), dateUtil().add(1, 'M')] },
            { label: '未来6月', value: [dateUtil(), dateUtil().add(6, 'M')] },
            { label: '未来1年', value: [dateUtil(), dateUtil().add(1, 'y')] },
          ],
        },
        valueResolve({ form, key }: ValueResolveContext) {
          if (form[key]) {
            const extra = {
              [`${String(key)}_st`]: form[key]?.[0],
              [`${String(key)}_ed`]: form[key]?.[1],
            };
            Reflect.deleteProperty(form, key);
            form.extra = extra;
          }
        },
      },
      addForm: { show: addShow },
      editForm: { show: editShow },
      column: {
        sorter: true,
        width: 180,
        formatter: ({ value }: ValueResolveContext) => {
          return value;
        },
      },
    },
  };
};

export const deleteButton = (params: {
  callback?: (arg: boolean) => Promise<void>;
  crudExpose: CrudExpose;
  removeFn: (arg: string[]) => Promise<boolean>;
  role?: string;
  selectedRowKeys: Ref<string[]>;
}) => {
  const { hasPermission } = useAccess();
  const { crudExpose, selectedRowKeys, role, removeFn, callback } = params;
  return {
    batchDelete: {
      show: role ? hasPermission(role) : true,
      text: $t('common.title.delete'),
      danger: true,
      click() {
        const { createConfirm, createMessage } = useMessage();
        if (selectedRowKeys.value?.length > 0) {
          createConfirm({
            title: '确认',
            iconType: 'warning',
            content: `确定要批量删除这${selectedRowKeys.value.length}条记录吗`,
            onOk: async () => {
              const flag = await removeFn(selectedRowKeys.value);
              if (callback && isFunction(callback)) {
                callback(flag);
              } else {
                if (flag) {
                  createMessage.success('删除成功');
                  selectedRowKeys.value = [];
                  await crudExpose?.doRefresh();
                }
              }
            },
          });
        } else {
          createMessage.warning('请先勾选您要删除的数据');
        }
      },
    },
  };
};

export enum DictValueType {
  number,
  boolean,
}

/** 请求后端字典的常量 */
export function backendDict(
  param: CodeQueryVO | string,
  valueType?: DictValueType,
) {
  let custom = {} as CodeQueryVO;
  custom = isString(param)
    ? { type: param, extendFirst: true }
    : (param as CodeQueryVO);
  return dict({
    cloneable: false,
    url: custom.type,
    custom: { ...custom, valueType },
    immediate: false,
    color: 'propType',
  });
}
/** 是-否  */
export const YES_NO_CONSTANT_DICT = dict({
  data: [
    { value: true, label: '是', color: 'success' },
    { value: false, label: '否', color: 'error' },
  ],
});

/** 是-否  */
export const YES_NO_NUMBER_CONSTANT_DICT = dict({
  data: [
    { value: 1, label: '是', color: 'success' },
    { value: 0, label: '否', color: 'error' },
  ],
});

/** 启用禁用  */
export const STATE_CONSTANT_DICT = dict({
  data: [
    { value: true, label: '启用', color: 'success' },
    { value: false, label: '禁用', color: 'error' },
  ],
});

/** 启用禁用  */
export const STATE_NUMBER_CONSTANT_DICT = dict({
  data: [
    { value: 1, label: '启用', color: 'success' },
    { value: 0, label: '禁用', color: 'error' },
  ],
});

export const transformRes = (props: TransformResProps) => {
  const { res } = props;
  return {
    currentPage: Number(res.current),
    pageSize: Number(res.size),
    total: Number(res.total),
    records: res.records,
  } as PageRes;
};
export const transformQuery = (query: PageQuery) => {
  const { page, form: model, sort } = query;
  const sizeObj = {
    current: page?.currentPage ?? 1,
    size: page?.pageSize ?? 20,
  };
  const sortObj = {
    sort: sort?.prop || undefined,
    order: sort?.order || undefined,
  };
  const extra = model?.extra;
  delete model?.extra;
  return {
    model,
    ...sizeObj,
    ...sortObj,
    extra,
  };
};
